/*
 * Server.h
 *
 *   Created on: 2010-2-9     
 *  Description: RPC-Server的抽象类
 *    Copyright: 2010 @ ICT Li Heyuan
 */

#ifndef SERVER_H_
#define SERVER_H_

#include "../method/RpcMethod.h"
#include "../method/RSAPubKeyMethod.h"
#include "../json_cpp/value.h"
#include "../util/Const.h"
#include "../util/Logger.h"
using Json::Value;

#include <map>
#include <string>
#include <iostream>
using std::cerr;
using std::endl;
using std::map;
using std::string;

class Server
{
public:
	/* 构造服务器
	 * @param port 绑定的端口号
	 * @param backlog listen的时候后备队列长度，默认20
	 * @param ip 绑定的IP地址，默认为any_addr即""
	 *
	 */
	Server(unsigned int port, int backlog = 20, const std::string ip = "") :
		_log_jsonr_rpc("json_rpc.log"), _log_server("rpc_server.log")
	{
		_log_server.info("json-rpc-e server started.");

		_addr.ip = ip;
		_addr.port = port;
		_backlog = backlog;

		//注册系统方法
		regSysMethod();
	}

	/* 析构造函数，用于释放资源等
	 */
	virtual ~Server()
	{

	}

	/* 服务器的初始化
	 * @return 成功返回true，失败返回false
	 */
	virtual bool init() = 0;

	/* 服务器开始工作
	 * 直到异常退出的话返回
	 */
	virtual void service() = 0;

	/* 获得服务器邦定的ip:port
	 * @return 服务器绑定的地址
	 */
	virtual EasyAddr getAddr()
	{
		return _addr;
	}

	/* 找rpc方法的处理函数
	 * @param method rpc方法的名字
	 * @return 如果找到了，返回rpcMethod指针，否则返回NULL
	 */
	virtual RpcMethod* findMethod(std::string method)
	{
		MethodMap::iterator itr = _methodMap.find(method);
		if (itr != _methodMap.end())
		{
			//找到了，返回
			return itr->second;
		}
		else
		{
			return NULL;
		}
	}

	/* 向map中添加RpcMethod
	 * @param method Rpc函数的注册名
	 * @param pMethod Rpc函数的指针
	 * @return 如果注册成功返回true，否则（如method已经被注册）返回false
	 */
	virtual bool addMethod(std::string method, RpcMethod* pMethod)
	{
		MethodMap::iterator itr = _methodMap.find(method);
		if (itr != _methodMap.end())
		{
			//已经注册该名字的Method了
			_log_server.error("method %s already exists , during register",
					method.c_str());
			return false;
		}
		else
		{
			//如果没有name的注册，则插入成功
			_methodMap.insert(MethodMap::value_type(method, pMethod));
			_log_server.info("rigister method %s", method.c_str());
			return true;
		}
	}

	/* 从map中移除Rpc函数，根据method名字
	 * @param 注册的Rpc函数名字
	 */
	virtual bool removeMethod(std::string method)
	{
		MethodMap::iterator itr = _methodMap.find(method);
		if (itr != _methodMap.end())
		{
			//已经注册该名字的Method了
			delete itr->second;

			_log_server.info("remove method %s", itr->first.c_str());
			return true;
		}
		else
		{
			//没有找到
			_log_server.error("not found method %s , during remove",
					itr->first.c_str());
			return false;
		}
	}

	/* 从map中移除Rpc函数，根据RpcMethod指针
	 * @param Rpc函数的指针
	 */
	virtual bool removeMethod(RpcMethod* pMetod)
	{
		//找到指针并删除
		MethodMap::iterator itr = _methodMap.begin();
		for (; itr != _methodMap.end(); itr++)
		{
			if (itr->second == pMetod)
			{
				delete itr->second;
				_methodMap.erase(itr);

				_log_server.info("remove method %s", itr->first.c_str());
				return true;
			}
		}
		_log_server.info("not found method pointer during remove");
		return false;
	}

	/*
	 * 注册系统所需要的方法
	 */
	virtual void regSysMethod()
	{
		//根据不同IP生成RSA公/私秘钥对
		this->addMethod(Const::SYS_RSA_PUBKEY, new RSAPubKeyMethod());
	}

	Logger& getJsonRpcLogger()
	{
		return _log_jsonr_rpc;
	}

	Logger& getNetLogger()
	{
		return _log_server;
	}

protected:

	//服务器绑定的地址：端口
	EasyAddr _addr;

	//后备队列
	int _backlog;

	//rpc函数的map映射
	typedef std::map<std::string, RpcMethod *> MethodMap;
	MethodMap _methodMap;

	//日志，记录sockFd的入出
	Logger _log_jsonr_rpc;

	//日志，记录rpcServer的逻辑
	Logger _log_server;
};

#endif /* SERVER_H_ */
